﻿/*
 * 名称：动态表格
 * 作者：朱晓华
 * 创建日期：2009-1-12
 * 更新日期：2009-8-4
 * 说明：使用本表格框架后，可在页面上随意增加表格的行，并根据设置好的tmplt行设置行中HTML的控件
 *      并可将全表中的值保存在一个hidden控件中
 * 使用说明：参见Moss文档
 * options：
 *		numColumn：	string 序号列dname，缺省为undefined
 *		onNewRow:		function(tr:jQuery)在添加新行时回调
 *     afterDeleteRow:  function()在删除行时回调
 * 修改历史：2009-1-24：将数据保存方式改为XML，引入了XML2JSON方法，并增加了Delete1Row方法
 *           2009-2-5：修订了只有一行时反序列化异常的Bug
 *           2009-2-23：增加了RowId，修改了checkbox赋值错误
 *           2009-2-26:增加了对Label和A标签的支持(其中A标签链接不具有通用性)
 *           2009-3-9: 增加了每行的随机dnmcRowId，增加numColumn，修订了层级选择器Bug造成的Disable错误，
 *           		增加了onNewRow回调函数
 *           2009-3-10:改clone为copy html以避免ie下的事件绑定异常问题
 *           2009-3-13:反序列化时如果没有Row.Id则生成一个随机id
 *           2009-5-7：增加afterDeleteRow回调函数
 *           2009-8-4: 黄平显(pcithpx) 增加对异常字符的转义(&,<,>,',") 
 *			 2009-12-22: 刘娟(pcitiuj) 增加支持js动态生成控件的功能。
[功能说明] 支持使用外部js在动态表格中生成控件
[添加原因] 当动态表格的某些控件需要使用js生成时，需要使用本功能（例如：需要在动态表格中使用MoneyCtrl控件时，由于MoneyCtrl.js支持控件生成，因此只需调用其代码即可。）
[使用方法] 在动态表格中需要使用js生成控件的地方添加<div type="JsCreate" Js="ControlGenerateFunctionName" JsCreateDname="DNameOfTheCreatedControl"> </div>做为容器。其中：
	type：固定为"JsCreate"作为标识，
	Js： 生成控件的function名称，生成的控件将位于容器中。
		 运行时，该function将接受(index, dname)参数，其中index是当前行的索引，dname是生成控件在动态表格中的dname
		 该function除了生成容器中的控件外，还将容器的id设置为"Parent"+dname+"_"+index（见随后示例）。
	JsCreateDname：生成控件的dname
[使用示例]
    function BenCiCell(index,dname) 
	{
		var MoneyCtrlID=dname+(index+1); 
		var ParentID="Parent"+dname+"_"+index;
		var eObject = "MoneyCtrl_"+MoneyCtrlID+"=new MoneyCtrl('"+MoneyCtrlID+"','￥','人民币',false,null,true,'"+ParentID+"','"+dname+"')";
		eval(eObject);
	}
	<tr dname="tmplt" index="%index%" style="display: none">
         <td><div style="width:130px" type="JsCreate" Js="BenCiCell" JsCreateDname="BenCi"></div></td>
[审核者] 黄平显 2009-12-22
 */
function DnmcTable(tableId, rowCheckName,prefix,options,dAtrbTag) {
	this.options=options||{};
    this.TableID = "#" + tableId;
    this.HiddenId = ((typeof (prefix) == "undefined" || prefix == "") ? "#processForm_" : prefix) + tableId + "Hdf";
    this.DName = (typeof (dAtrbTag) == "undefined" || dAtrbTag == "") ? "dname" : dAtrbTag;
    this.Region = options.region ? options.region : window.document;
    this.OnBeforeRowSerial = options.onBeforeRowSerial;
    this.RowCheckName = "["+this.DName+"=" + rowCheckName + "]";
    this.RowId = 1;
	//生成一个随即ID
	DnmcTable.prototype.generateId = function(){
		var id="dnmcTableRow"+Math.random().toString().replace(".","");
		while ($("#"+id).length!=0){
			id="dnmcTableRow"+Math.random().toString().replace(".","");
		}
		return id;
	}

    //向动态表格中添加一行，并且设置行中的控件值为初始值(dvalue)
	DnmcTable.prototype.Add = function () {
	    var tr = $("<tr>" + $(this.TableID + " [" + this.DName + "='tmplt']tr:first", this.Region).html() + "</tr>");
	    var dnmcRowId = this.generateId();
	    tr.attr("id", dnmcRowId);
	    tr.attr("align", "center");
	    tr.html(tr.html().replace(/%index%/g, this.RowId).replace(/%dnmcRowId%/g, dnmcRowId));
	    $("[" + this.DName + "]", tr).each(function () {
	        var ji = $(this);
	        if (ji.attr("type") == "checkbox") {
	            ji.attr("checked", ji.attr("dValue"));
	        }
	        else if (ji.attr("tagname") == "LABEL" || ji.attr("tagname") == "A") {
	            ji.text(ji.attr("dValue"));
	            ji.attr("title", ji.attr("dValue"));
	        }
	        else { ji.val(ji.attr("dValue")); }
	    });
	    //添加前事件---(pcittfl 20100602)
	    if (DnmcTable.BeforeAdd != null) {
	        //只有返回false才中断,如果返回undefined就放过去
	        if (DnmcTable.BeforeAdd(this) == false) {
	            return false;
	        }
	    }

	    //创建js objects，刘娟添加
	    var RowId = this.RowId; var JsToExe = "";
	    $("[type=JsCreate]", tr).each(function () {
	        var ParentDiv = $(this); var JsCreateDname = ParentDiv.attr("JsCreateDname");
	        ParentDiv.attr("id", "Parent" + JsCreateDname + "_" + RowId);
	        JsToExe += ParentDiv.attr("Js") + "(" + RowId + ",'" + JsCreateDname + "');";
	    });

	    this.RowId++;
	    if (this.options.numColumn) {
	        $("[" + this.DName + "='" + this.options.numColumn + "']", tr).text($(this.TableID + " tr[" + this.DName + "='dataRow']", this.Region).length + 1);
	    }
	    tr.attr(this.DName, "dataRow");
	    tr.show(); 
	    $(this.TableID, this.Region).append(tr);
	    if (this.options.onNewRow) { this.options.onNewRow(tr); }
	    if (JsToExe != "") eval(JsToExe);
	    //添加后事件
	    if (this.options.AfterAdd != null) {
	        this.options.AfterAdd(dnmcRowId);
	    }
	};

	DnmcTable.prototype.ResetNumberColumn = function(){
	    $("td[" + this.DName + "='" + this.options.numColumn + "']", $(this.TableID, this.Region))
		.each(function (i) {
				this.innerHTML=i;
		})
	}
    //删除动态表格中选中的行
    DnmcTable.prototype.Delete = function() {
        var method=this.options;
        $(this.TableID + " [" + this.DName + "='dataRow']tr:has(" + this.RowCheckName + ":checked)", this.Region).each(function () {
            if(method.beforeDeleteRow){method.beforeDeleteRow();}
            $(this).remove();
            if(method.afterDeleteRow){method.afterDeleteRow();}
        });
		if (this.options.numColumn) {
			this.ResetNumberColumn();
		}
    };
     //隐藏动态表格中选中的行
    DnmcTable.prototype.Hide = function() {
        var dltRow=this.options.afterHideRow;

        $(this.TableID + " [" + this.DName + "='dataRow']tr:has(" + this.RowCheckName + ":checked)", this.Region).each(function () {
            $(this).hide();
            if(dltRow){dltRow();}
        });
		if (this.options.numColumn) {
			this.ResetNumberColumn();
		}
    };
      //显示动态表格中选中的行
    DnmcTable.prototype.Show = function() {
        var dltRow=this.options.afterShowRow;
        $(this.TableID + " [" + this.DName + "='dataRow']tr:has(" + this.RowCheckName + ":checked)", this.Region).each(function () {
            $(this).show();
            if(dltRow){dltRow();}
        });
		if (this.options.numColumn) {
			this.ResetNumberColumn();
		}
    };
	
	//新删除[删除按钮]所在行，需要DnmcTable对象实例
	DnmcTable.prototype.Delete1RowEx = function(sender){
	    $(sender, this.Region).attr("id", "deletingRow");
	    if(this.options.beforeDeleteRow){this.options.beforeDeleteRow();}
	    $("tr:has(#deletingRow):last").remove();
	    if(this.options.afterDeleteRow){this.options.afterDeleteRow();}
		this.ResetNumberColumn();
	}
    //将动态表格中的控件序列化为一个XML值
	DnmcTable.prototype.Serialize = function () {
	   // debugger;
	    var tDName = this.DName;
	    var tOnBeforeRowSerial = this.OnBeforeRowSerial; //行序列化前，执行的动作；
	    var rows = $(this.TableID + " tr[" + tDName + "='dataRow']", this.Region);
	    if (rows.length < 1) {
	        $(this.HiddenId, this.Region).val("");
	        return;
	    }

	    var s = "<xml>";
	    rows.each(function () {
	        if (tOnBeforeRowSerial) { tOnBeforeRowSerial(this); }; //行序列化前，执行的动作；2012-3-12晚 liangning

	        var tr = $(this);
	        s += "<row id='" + this.id + "'>";
	        $("[" + tDName + "]", tr).each(function () {
	            var ji = $(this);
	            if (ji.attr("type") == "checkbox") {
	                s += "<" + ji.attr(tDName) + ">"
                    + ji.attr("checked")
                    + "</" + ji.attr(tDName) + ">";
	            }
	            else if (ji.attr("type") == "radio") //添加对radio的支持
	            {
	                s += "<" + ji.attr(tDName) + ">"
                    + ji.attr("checked")
                    + "</" + ji.attr(tDName) + ">";
	            }
	            else if (ji.attr("tagname") == "LABEL" || ji.attr("tagname") == "A") {
	                s += "<" + ji.attr(tDName) + ">"
	                //增加HTML转义功能,以满足有HTML的内容---pcithpx(20090804)
                   + DnmcTable.EnHTMLCode(encodeURI(ji.html()))
                   + "</" + ji.attr(tDName) + ">";
	            }
	            else {
	                s += "<" + ji.attr(tDName) + ">"
	                //增加HTML转义功能,以满足有HTML的内容---pcithpx(20090804)
                    + DnmcTable.EnHTMLCode(encodeURI(ji.val()))
                    + "</" + ji.attr(tDName) + ">";
	            }
	        });
	        s += "</row>";
	    });
	    s += "</xml>"
	    $(this.HiddenId, this.Region).val(s);
	};
    //根据一行的xml得到的json对象创建动态表格
	DnmcTable.prototype.Add1Row = function (row) {
	    var tr = $("<tr>" + $(this.TableID + " [" + this.DName + "='tmplt']tr:first", this.Region).html() + "</tr>");
	    var dnmcRowId = row.id;
	    if (dnmcRowId == '' || dnmcRowId == undefined) {
	        dnmcRowId = this.generateId();
	    }
	    tr.attr("id", dnmcRowId);
	    tr.attr("align", "center");
	    tr.html(tr.html().replace(/%index%/g, this.RowId).replace(/%dnmcRowId%/g, dnmcRowId));
	    var RowId = this.RowId;
	    $(this.TableID, this.Region).append(tr); //已添加Html
	    //创建js objects，刘娟添加
	    $("[type=JsCreate]", tr).each(function () {
	        var ParentDiv = $(this); var JsCreateDname = ParentDiv.attr("JsCreateDname");
	        ParentDiv.attr("id", "Parent" + JsCreateDname + "_" + RowId);
	        var temp = ParentDiv.attr("Js") + "(" + RowId + ",'" + JsCreateDname + "');";
	        eval(temp);
	    });
	    this.RowId++;

	    for (key in row) {
	        var jo = $("[" + this.DName + "=" + key + "]", tr);
	        if (jo.attr("type") == "checkbox") {
	            if (row[key] == "true") jo.attr("checked", "true");
	            else jo.removeAttr("checked");
	        }
	        else if (jo.attr("type") == "radio") {
	            if (row[key] == "true") jo.attr("checked", "true");
	            else jo.removeAttr("checked");
	        }
	        else if (jo.attr("tagname") == "LABEL" || jo.attr("tagname") == "A") {
	            if (decodeURI(row[key]) == 'true') {
	                jo.html(decodeURI("是"))
	            }
	            else if (decodeURI(row[key]) == 'false') {
	                jo.html(decodeURI("否"))
	            }
	            else {
	                //增加HTML转义功能,以满足有HTML的内容---pcithpx(20090804)
	                jo.html(DnmcTable.DeHTMLCode(decodeURI(row[key])));
	                jo.attr("title", DnmcTable.DeHTMLCode(decodeURI(row[key])));
	            }
	            if (jo.attr("tagname") == "A") {
	                //增加HTML转义功能,以满足有HTML的内容---pcithpx(20090804)
	                //jo.html(decodeURI(row[key]));
	                //用A标签的TEXT绑定HREF属性，如有需要可以统一
	                jo.attr("href", DnmcTable.DeHTMLCode(decodeURI(row[key])));
	            }
	        }
	        else {
	            if (decodeURI(row[key]) == 'true') {
	                jo.val(decodeURI("是"));
	            }
	            else if (decodeURI(row[key]) == 'false') {
	                jo.val(decodeURI("否"));
	            }
	            else {
	                //增加HTML转义功能,以满足有HTML的内容---pcithpx(20090804)
	                jo.val(DnmcTable.DeHTMLCode(decodeURI(row[key])));
	            }
	        } //if
	    } //for

	    if (this.options.numColumn) {
	        $("[" + this.DName + "='" + this.options.numColumn + "']", tr).text(
			$(this.TableID + " tr[" + this.DName + "='dataRow']").length + 1);
	    }


	    tr.attr(this.DName, "dataRow");
	    if (this.options.onNewRow) { this.options.onNewRow(tr); }
	    tr.show();
	    return tr;//添加返回“序列化后的行”
	}

    //将XML字符串反序列化为动态表格中的控件并设置值
	DnmcTable.prototype.DeSerialize = function () {
	    var tr, kv, jo, tagName;
	    $(this.TableID + " [" + this.DName + "='dataRow']tr", this.Region).each(function () { $(this).remove(); });
	    var rows = $.xml2json($(this.HiddenId, this.Region).val());
	    if (rows.row == undefined) {
	        this.Add();
	        return;
	    }
	    var aimTR = null;
	    if (rows.row.length == undefined) {
	        aimTR = this.Add1Row(rows.row);
	        if (this.options.AfterDeSeri != null) {
	            this.options.AfterDeSeri(aimTR);
	        }
	    }
	    this.RowsCount = rows.row.length;
	    for (var i = 0; i < this.RowsCount;
         i++) {
	        aimTR = this.Add1Row(rows.row[i]);
	        if (this.options.AfterDeSeri != null) {
	            this.options.AfterDeSeri(aimTR);
	        }
	    }
	    //        if ( this.options.AfterDeSeri != null )
	    //        {
	    //            this.options.AfterDeSeri() ;
	    //        }
	}

    //禁止动态表格内所有控件
    DnmcTable.prototype.Disable = function(){
        $(this.TableID+"BtnAdd").hide();
        $(this.TableID+"BtnDlt").hide();
        $("td ["+this.DName+"]",$(this.TableID)).attr("disabled","disabled");
        $("td input[type='button']",$(this.TableID)).hide();
        $("td input[class='btMiniAddSch']",$(this.TableID)).hide();
    }
    
    //使禁止状态下的动态表格内所有控件恢复编辑状态
    DnmcTable.prototype.UnDisable = function(){
        $(this.TableID+"BtnAdd").show();
        $(this.TableID+"BtnDlt").show();
        $("td ["+this.DName+"]",$(this.TableID)).attr("disabled","");
        $("td input[type='button']",$(this.TableID)).show();
    }
     //只读动态表格内所有控件
    DnmcTable.prototype.ReadOnly = function(){
        $(this.TableID+"BtnAdd").hide();
        $(this.TableID+"BtnDlt").hide();
        $("td ["+this.DName+"]",$(this.TableID)).attr("readOnly","readOnly");
        $("td select["+this.DName+"]",$(this.TableID)).attr("disabled","disabled");
    }
}
//初始化动态表格
DnmcTable.Ini = function (dnmcTable){//debugger
    $(dnmcTable.TableID+"BtnAdd").bind("click",function(){dnmcTable.Add();});
    $(dnmcTable.TableID+"BtnDlt").bind("click",function(){dnmcTable.Delete();});
    $(dnmcTable.TableID+"BtnHid").bind("click",function(){dnmcTable.Hide();});
    $(dnmcTable.TableID+"BtnShow").bind("click",function(){dnmcTable.Show();});
    dnmcTable.DeSerialize();
}
//删除[删除按钮]所在行
DnmcTable.Delete1Row = function(sender,dtInstance){
    $(sender).attr("id","deletingRow");
    $("tr:has(#deletingRow):last").remove();
    //删除后事件---(pcittfl 20100602)
    if (typeof dtInstance != 'undefined'){
        if(typeof dtInstance.options.afterDeleteRow != 'undefined'){dtInstance.options.afterDeleteRow();}
    }
}

//对HTML字符进行转义---pcithpx(20090804)
DnmcTable.EnHTMLCode = function(str){
	//  &lt;            <        小于号  
	//  &gt;            >        大于号 
	//  &amp;           &        和  
	//  &apos;          '         单引号 
	//  &quot;          "         双引号 

       var ret = str;
	   ret = ret.replace(/&/g,"&amp;" );
	   ret = ret.replace(/</g,"&lt;" );
	   ret = ret.replace(/>/g,"&gt;" );
	   ret = ret.replace(/'/g,"&apos;" );
	   ret = ret.replace(/\"/g,"&quot;" );
	   return ret;
}
  
//对HTML字符进行反转义---pcithpx(20090804)
DnmcTable.DeHTMLCode = function(str){
       var ret = str;	   
	   ret = ret.replace(/&lt;/g,"<" );
	   ret = ret.replace(/&gt;/g,">" );
	   ret = ret.replace(/&apos;/g,"'" );
	   ret = ret.replace(/&quot;/g,"\"" );
	   ret = ret.replace(/&amp;/g,"&" );
	   return ret;
}

